// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2023.
 * Description: irq: merge high-precision timer can reduce interrupts and context switches
 * Author: langfei
 * Create: 2023-12-25
 */

#include <linux/percpu-defs.h>
#include <linux/fs.h>
#include <linux/kernel_stat.h>

#include "proc_high_precision.h"

static DEFINE_PER_CPU(s64, user_dif);

void get_old_user_time(u64 *user, struct kernel_cpustat *kcpustat, int i)
{
	u64 tmp = *user;
	u64 *cpustat = kcpustat->cpustat;

	if (correct_proc_stat) {
		if (per_cpu(period_divisor, i) != 0) {
			if (per_cpu(user_dif, i) < (s64)(cpustat[CPUTIME_IDLE] -
						get_idle_time(kcpustat, i))) {
				tmp += cpustat[CPUTIME_IDLE] - get_idle_time(kcpustat, i);
			} else {
				tmp += per_cpu(user_dif, i);
			}
		} else {
			tmp += per_cpu(user_dif, i);
		}
	}
	*user = tmp;
}

void get_new_user_time(u64 *user, struct kernel_cpustat *kcpustat, int i)
{
	u64 tmp = *user;
	u64 *cpustat = kcpustat->cpustat;

	if (correct_proc_stat) {
		if (per_cpu(period_divisor, i) != 0) {
			if (per_cpu(user_dif, i) < (s64)(cpustat[CPUTIME_IDLE] -
						get_idle_time(kcpustat, i))) {
				per_cpu(user_dif, i) = cpustat[CPUTIME_IDLE] -
					get_idle_time(kcpustat, i);
				tmp += cpustat[CPUTIME_IDLE] - get_idle_time(kcpustat, i);
			} else {
				tmp += per_cpu(user_dif, i);
			}
		} else {
			tmp += per_cpu(user_dif, i);
		}
	}
	*user = tmp;
}

